﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using QW.Core;
using QW.Core.AutoTasks;
using QW.Core.Exceptions;

namespace QW.Found.AutoTasks
{
    /// <summary>
    /// 事件中心基类
    /// </summary>
    public abstract class BaseTaskCenter<T> : ITaskCenter
    {
        /// <summary>
        /// 任务描述
        /// </summary>
        protected List<TaskDescriptor<T>> TaskDescriptors = new List<TaskDescriptor<T>>();
        /// <summary>
        /// 改变触发条件
        /// </summary>
        /// <param name="name"></param>
        /// <param name="interval"></param>
        public void ChangeTrigger(string name, TaskInterval interval)
        {
            var descriptor = TaskDescriptors.FirstOrDefault(p => p.Name == name);
            if (descriptor == null)
                throw new QWBaseBusinessException("task_notfound:定时任务不存在");
            ChangeTrigger(descriptor, interval);
        }
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="tasks"></param>
        /// <exception cref="Exception"></exception>
        public void Register(IEnumerable<ITask> tasks)
        {
            TaskDescriptors = new List<TaskDescriptor<T>>();
            foreach (var task in tasks)
            {
                var type = task.GetType();
                var methods = type.GetMethods();
                foreach (var method in methods)
                {
                    var attr = method.GetCustomAttribute<TaskAttribute>(false);
                    if (attr == null)
                        continue;//忽略无TaskAttribute属性方法

                    var identity = $"{method.ReflectedType.FullName}<{method.Name}>";
                    var parameters = method.GetParameters();

                    if (parameters.Length > 0)
                        throw new Exception($"Task方法不支持传递参数");

                    var descriptor = new TaskDescriptor<T>
                    {
                        Name = attr.Name,
                        Group = attr.Group,
                        Type = type,
                        Logger = attr.Logger,
                        Locker = attr.Locker,
                        LockerTimeOut = attr.LockerTimeOut,
                        Instance = task,
                        Handler = FastInvoke.GetMethodInvoker(method),
                        Interval = attr.Interval,
                    };
                    TaskDescriptors.Add(descriptor);
                }
            }
            foreach (var descriptor in TaskDescriptors)
                Subscribe(descriptor);
        }

        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="descriptor"></param>
        protected abstract void Subscribe(TaskDescriptor<T> descriptor);
        /// <summary>
        /// 改变触发条件
        /// </summary>
        /// <param name="descriptor"></param>
        /// <param name="interval"></param>
        protected abstract void ChangeTrigger(TaskDescriptor<T> descriptor, TaskInterval interval);
        /// <summary>
        /// 启动
        /// </summary>
        public abstract void Start();
        /// <summary>
        /// 停止
        /// </summary>
        public abstract void Stop();
        /// <summary>
        /// 析构
        /// </summary>
        public virtual void Dispose()
        {
            TaskDescriptors.Clear();
        }


    }
}
